<template>
  <div class="layout">
    <Layout>
      <Sider hide-trigger class="sideBar">
        <!-- 侧边栏树形控件 -->
        <!-- data5中数据增加，因为绑定了renderContent所以可以实现添加元素的动态渲染 -->
        <Tree
          :data="initData"
          :render="renderContent"
          class="demo-tree-render"
          @on-contextmenu="handleContextMenu"
          @on-select-change="showContent"
          show-checkbox
          ref="tree"
        >
          <!-- 如何获取data呢？ -->
          <template slot="contextMenu">
            <DropdownItem @click.native="handleContextMenuEdit"
              >重命名</DropdownItem
            >
            <DropdownItem @click.native="handleContextMenuCopy"
              >复制</DropdownItem
            >
            <DropdownItem @click.native="handleContextMenuPaste"
              >粘贴</DropdownItem
            >
            <DropdownItem @click.native="handleContextMenuCut"
              >剪切</DropdownItem
            >
            <DropdownItem
              @click.native="handleContextMenuDelete"
              style="color: #ed4014"
              >删除</DropdownItem
            >
          </template>
          <!-- <template slot="inputField">
            
          </template> -->
        </Tree>

        <!-- 输入框 -->
        <!-- <a-input
          :visible="setNameDialogVisiblility"
          placeholder="Basic usage"
          allowClear
          addonAfter
          v-model="inputText"
          @pressEnter="updateTree(inputText)"
        /> -->
        <!-- v-on绑定一下~~~ -->
        <Input
          v-model="inputText"
          placeholder="新增文件需要先输入文件名！"
          clearable
          style="width: 200px"
          @on-enter="enterPress(inputText)"
          @on-change="changeTitle(inputText)"
        />
      </Sider>

      <Layout>
        <Header :pathName="initData" class="header1">
          <!-- <Breadcrumb>
            <BreadcrumbItem>root</BreadcrumbItem>
            从children数组的title中获取数据
            <BreadcrumbItem>父级目录</BreadcrumbItem>
            从children数组的children数组的title中获取数据
            <BreadcrumbItem>子级目录</BreadcrumbItem>
          </Breadcrumb> -->
        </Header>
        <Content class="content1">{{ defaultText }}</Content>
      </Layout>
    </Layout>
  </div>
</template>

<script>
import { mapState, mapActions, mapMutations } from 'vuex'

export default {
  name: 'Home',
  data() {
    return {
      editState: false,
      inputContent: '',
      initData: [
        {
          title: 'root',
          expand: true,
          contextmenu: true,
          // 使用强大的 Render 函数可以自定义节点显示内容和交互，比如添加图标，按钮等。
          // 直接添加dom节点
          // render 的data是啥，data是组件提供的当前节点的数据。包括这个节点的children节点。
          render: (h, { data }) => {
            return h(
              'span',
              {
                style: {
                  display: 'flex',
                  width: '100%'
                }
              },
              [
                h('span', [
                  h('Icon', {
                    props: {
                      type: 'ios-folder-outline'
                    },
                    style: {
                      marginRight: '8px'
                    }
                  }),
                  h('span', data.title)
                ]),
                // 后面的按钮的初始化渲染
                h(
                  // 渲染一个空格
                  'span',
                  {
                    style: {
                      display: 'flex',
                      float: 'right',
                      // 和右边的距离
                      marginRight: '70px'
                    }
                  },
                  // 渲染添加按钮绑定点击事件
                  [
                    // 添加按钮 这个是root
                    h(
                      'Button',
                      {
                        // 合并两个对象
                        // 基本用法 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
                        props: Object.assign({}, this.buttonProps, {
                          type: 'success'
                        }),
                        // 按钮的宽度
                        style: {
                          width: '90px',
                          marginLeft: '10px'
                        },
                        on: {
                          click: () => {
                            this.append(data)
                            this.updateCache(data)
                          }
                        }
                      },
                      '新增文件夹'
                    ),
                    // 添加按钮 这个是root
                    h(
                      'Button',
                      {
                        // 合并两个对象
                        // 基本用法 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
                        props: Object.assign({}, this.buttonProps, {
                          type: 'success'
                        }),
                        // 按钮的宽度
                        style: {
                          width: '70px',
                          marginLeft: '10px'
                        },
                        on: {
                          click: () => {
                            this.add(data)
                            this.updateCache(data)
                          }
                        }
                      },
                      '新增文件'
                    ),

                    // 重置按钮 这个是root
                    h(
                      'Button',
                      {
                        // 合并两个对象
                        // 基本用法 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
                        props: Object.assign({}, this.buttonProps, {
                          type: 'error'
                        }),
                        // 按钮的宽度
                        style: {
                          width: '50px',
                          marginLeft: '10px'
                        },
                        on: {
                          click: () => {
                            this.resetChildren(data)
                            this.updateCache(data)
                          }
                        }
                      },
                      '重置'
                    ),

                    // 恢复按钮
                    h(
                      'Button',
                      {
                        // 合并两个对象
                        // 基本用法 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
                        props: Object.assign({}, this.buttonProps, {
                          type: 'info'
                        }),
                        // 按钮的宽度
                        style: {
                          width: '50px',
                          marginLeft: '10px'
                        },
                        on: {
                          click: () => {
                            this.initChildren(data)
                            this.updateCache(data)
                          }
                        }
                      },
                      '恢复'
                    )
                  ]
                )
              ]
            )
          },
          // 节点数组，读取保存好的children
          children: []
        }
      ],
      buttonProps: {
        type: 'default',
        size: 'small'
      },
      inputText: '',
      contextData: null
    }
  },

  // created没办法调用methods里面的function,所以this.$store.dispatch和mapActions还是有区别的
  created() {
    // 从vuex中获得dynamic数组
    this.$store.dispatch('getDynamicChildren')
    // 从localStorage中获取字符串转成json，然后更vuex的dynamic数组
    this.$store.dispatch('setCache')
  },

  computed: {
    ...mapState([
      'dynamicChildren',
      'cache',
      'defaultText',
      'newName',
      'oldName',
      // 'inputText',
      'copyTitle'
      // 'inputContent'
    ])
  },

  methods: {
    ...mapActions([]),
    ...mapMutations([
      'renderContentVuex',
      // 'initChildren',
      // 'resetChildren',
      // 'updateCache',
      // 'enterPress',
      'clearInput',
      // 'updateTree',
      'append',
      'remove',
      'copy',
      'paste',
      'json2LocalStorage',
      'localStorage2Json',
      'setTitle',
      'showContent'
    ]),
    // 动态渲染节点
    // root <Array>：树的根节点
    // node <Object>：当前节点
    // data <Object>：当前节点的数据
    renderContent(h, { root, node, data }) {
      // 新增节点的模板
      return h(
        'span',
        {
          class: 'hhhaha',
          style: {
            // 修改成flex布局自定义行的宽度
            display: 'flex',
            width: '100%'
          },
          on: {
            click: () => {
              // 点击Tree节点触发
              data.editState ? '' : this.handleClickTreeNode(data)
            }
          }
        },
        [
          h('span', [
            // 图表
            h('Icon', {
              props: {
                type: 'ios-folder-outline'
              },
              style: {
                marginRight: '8px'
              }
            }),
            // 名字 或者 输入框
            h(`${data.editState ? '' : 'span'}`, data.title),
            h(`${data.editState ? 'input' : ''}`, {
              attrs: {
                value: `${data.editState ? data.title : ''}`,
                autofocus: 'true'
              },
              style: {
                width: '12rem',
                cursor: 'auto'
              },
              on: {
                change: event => {
                  this.inputContent = event.target.value
                }
              }
            })
          ]),
          // 添加删除按钮的渲染模板
          h(
            `${data.editState ? '' : 'span'}`,
            {
              class: 'btnNone',
              style: { marginLeft: '1rem' }
            },
            [
              // 操作按钮部分
              // 编辑按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-brush-outline'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  lineHeight: '0',
                  padding: '0',
                  height: '1.4rem'
                },
                on: {
                  click: () => {
                    this.editTree(data)
                  }
                }
              }),
              // 添加文件夹按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-folder-open-outline'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  lineHeight: '0',
                  padding: '0',
                  height: '1.4rem'
                },

                // 绑定添加按钮的点击事件
                on: {
                  // 点击添加data
                  click: () => {
                    // this.showAddInput()
                    // append data 应该在获取输入框的名字之后
                    this.append(data)
                    this.updateCache(data)
                  }
                }
              }),
              // 添加文件按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-add'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  lineHeight: '0',
                  padding: '0',
                  height: '1.4rem'
                },
                // 绑定添加按钮的点击事件
                on: {
                  // 点击添加data
                  click: () => {
                    // this.showAddInput()
                    // append data 应该在获取输入框的名字之后
                    this.add(data)
                    this.updateCache(data)
                  }
                }
              }),

              // 删除按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-remove'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  padding: '0',
                  lineHeight: '0',
                  height: '1.4rem'
                },
                // 绑定删除按钮的点击事件
                on: {
                  click: () => {
                    this.remove(root, node, data)
                    this.updateCache(data)
                  }
                }
              }),
              // 复制按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-copy-outline'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  padding: '0',
                  lineHeight: '0',
                  height: '1.4rem'
                },
                // 绑定删除按钮的点击事件
                on: {
                  click: () => {
                    this.copy(data)
                    this.updateCache(data)
                    this.getAllData()
                    // this.remove(root, node, data)
                  }
                }
              }),

              // 粘贴按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-clipboard-outline'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  padding: '0',
                  lineHeight: '0',
                  height: '1.4rem'
                },
                // 绑定删除按钮的点击事件
                on: {
                  click: () => {
                    this.paste(data)
                    this.updateCache(data)
                  }
                }
              }),

              // 剪切按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'ios-cut'
                }),
                style: {
                  marginRight: '8px',
                  borderRadius: '50%',
                  width: '1.5rem',
                  padding: '0',
                  lineHeight: '0',
                  height: '1.4rem'
                },
                // 绑定删除按钮的点击事件
                on: {
                  click: () => {
                    this.cut(root, node, data)
                    this.updateCache(data)
                  }
                }
              })
            ]
          ),
          // 确认取消和修改的部分
          h(
            `${data.editState ? 'span' : ''}`,
            {
              style: {
                marginLeft: '.5rem'
              }
            },
            [
              // 确认按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'md-checkmark'
                }),
                style: {
                  // marginRight: '8px',
                  border: 0,
                  background: 'rgba(0,0,0,0)',
                  fontSize: '1.3rem',
                  outline: 'none'
                },
                on: {
                  click: event => {
                    this.confirmTheChange(data)
                  }
                }
              }),
              // 取消按钮
              h('Button', {
                props: Object.assign({}, this.buttonProps, {
                  icon: 'md-close'
                }),
                style: {
                  border: '0',
                  background: 'rgba(0,0,0,0)',
                  fontSize: '1.3rem',
                  outline: 'none'
                },
                on: {
                  click: () => {
                    this.CancelChange(data)
                  }
                }
              })
            ]
          )
        ]
      )
    },

    // 初始化操作把数据恢复到数组中
    // 把vuex的 cache| dynamicChildren 恢复到页面上
    initChildren(data) {
      console.log('data', data)
      console.log('localStorage', localStorage)
      if (
        localStorage.getItem('localData') &&
        localStorage.getItem('localData').length != 0
      ) {
        console.log('有本地缓存')
        console.log('this.cache', this.cache)
        this.$set(data, 'children', this.cache)
      } else {
        console.log('没有本地缓存')
        // this.localStorage2Json()
        this.$set(data, 'children', this.dynamicChildren)
      }
    },

    // getAllData() {
    //   console.log('all data', this.$refs.tree.getCheckedAndIndeterminateNodes())
    // },

    // 重置children数组到默认的状态
    // dynamicChildren是本地json，cache是当前页面的渲染数组
    resetChildren(data) {
      this.$set(data, 'children', this.dynamicChildren)
      // 不能直接修改cache和dynamicChildren，这两个是vuex中的
      this.$store.commit('cache', this.dynamicChildren)
      console.log('resetChildren重置cache', this.cache)
    },

    // 更新cache数组，原来的数据做增量更新，不是简单的覆盖操作！
    updateCache(data) {
      // this.$set(this.dynamicChildren, 'children', data.children)
      // 不好！data是当前节点的信息不是全部节点的信息
      // 需要获取全部节点的信息，在哪？
      // 如何更改cache里面当前节点的信息啊？
      // 可以获取其父级组件然后更新之
      this.$store.commit('cache', data.children)
      // this.cache = data.children
      // 不能直接修改cache
      this.json2LocalStorage(this.cache)
    },
    // updateCacheCopy(data) {
    //   this.$store.commit('cache', data.children)
    //   this.json2LocalStorage(this.cache)
    // },
    // updateCacheCut(data) {
    //   this.$store.commit('cacheCut', data.children)
    //   this.json2LocalStorage(this.cache)
    // },

    // 更新事件，点击确认或者内容change时会触发
    changeTitle(value) {
      // children
      // 显示一个输入框，从输入框中获取名字
      this.addInputVisibility = false
      console.log(value)
      if (value !== '') {
        if (value.split('.')[1] === 'text') {
          console.log(value.split('.')[1])
          this.default = 'text default'
        } else if (value.split('.')[1] === 'js') {
          console.log(value.split('.')[1])
          this.default = 'js default'
        } else if (value.split('.')[1] === 'ts') {
          console.log(value.split('.')[1])
          this.default = 'ts default'
        } else if (value.split('.')[1] === 'json') {
          console.log(value.split('.')[1])
          this.default = 'json default'
        }
        this.setTitle(value)
      }
    },

    // 确定点击事件
    enterPress(inputValue) {
      // 不为空才添加
      if (inputValue.trim().length <= 0) {
        return this.$message.warning('文本框内容不能为空')
      }
      this.changeTitle(inputValue)
      this.clearInput()
    },

    // 新建文件夹操作
    append(data) {
      if (this.newName) {
        this.$store.dispatch('appendAsync', data)
      } else {
        this.$Message.error('请输入文件名称！')
      }
    },
    appendChildren(data) {
      if (this.copyChildren) {
        this.$store.dispatch('appendChildrenAsync', data)
      } else {
        this.$Message.error('请输入文件名称！')
      }
    },

    // 新建文件操作
    add(data) {
      if (this.newName) {
        this.$store.dispatch('addAsync', data)
      } else {
        this.$Message.error('请输入文件名称！')
      }
    },

    // 删除操作
    // remove(root, node, data) {
    //   event.stopPropagation()
    //   // this.$store.dispatch('removeAsync', root, node, data)
    //   const parentKey = root.find(el => el === node).parent
    //   const parent = root.find(el => el.nodeKey === parentKey).node
    //   const index = parent.children.indexOf(data)
    //   parent.children.splice(index, 1)
    // },
    remove(root, node, data) {
      this.$Modal.confirm({
        title: '提示',
        content: `您确定删除 “${data.title}” 吗？`,
        onOk: () => {
          const parentKey = root.find(el => el === node).parent
          const parent = root.find(el => el.nodeKey === parentKey).node
          const index = parent.children.indexOf(data)
          parent.children.splice(index, 1)
          this.$Message.info('删除成功')
        },
        onCancel: () => {
          this.$Message.info('取消')
        }
      })
    },

    // 复制操作
    // 就是复制当前节点的信息到一个地方
    copy(data) {
      console.log('copy data', data)
      // this.copyTitle = data.title
      this.$store.dispatch('copyAsync', data)
      // this.$store.dispatch('copyChildrenAsync', data)
    },

    // 粘贴操作
    paste(data) {
      this.$store.dispatch('pasteAsync', data)
      // this.$set(data, 'children', children)
    },

    // 剪切操作
    cut(root, node, data) {
      // this.copy(data)
      // this.remove(root, node, data)
      this.$store.dispatch('copyAsync', data)
      this.remove(root, node, data)
    },

    // 自动保存, 将网页中使用的json数据保存起来
    saveCache() {
      console.log('autoSave')
      // 把dynamicChildren的值存到localStorage中，json2local
      this.json2LocalStorage(this.cache)
    },

    handleContextMenu(data) {
      this.contextData = data
    },

    handleContextMenuEdit() {
      this.$Message.info('Click edit of ' + this.contextData.title)
      // console.log(data)
    },

    handleContextMenuDelete() {
      this.$Message.info('Click delete of ' + this.contextData.title)
    },

    handleContextMenuCopy() {
      this.$Message.info('Click copy of ' + this.contextData.title)
    },

    handleContextMenuPaste() {
      this.$Message.info('Click paste of ' + this.contextData.title)
    },

    handleContextMenuCut() {
      this.$Message.info('Click cut of ' + this.contextData.title)
    },

    // 控制Tree当前状态函数
    setStates(data) {
      var editState = data.editState
      if (editState) {
        this.$set(data, 'editState', false)
      } else {
        this.$set(data, 'editState', true)
      }
    },

    // Tree修改按钮
    editTree(data) {
      event.stopPropagation()
      // this.inputContent = data.title
      this.$store.dispatch('editTreeAsync', data)
      // this.oldName = data.title
      this.setStates(data)
    },

    // 确认修改树节点
    confirmTheChange(data) {
      if (!this.inputContent) {
        this.$Notice.warning({
          title: '当前输入有误'
        })
      } else {
        if (this.oldName !== this.inputContent) {
          this.$Modal.confirm({
            title: '提示',
            content: `您确定将  “${this.oldName}”  重命名为 “ ${this.inputContent} ” 吗？`,
            onOk: () => {
              data.title = this.inputContent
              // this.setTitle(inputContent)
              this.$Message.info('修改成功')
            },
            onCancel: () => {
              this.$Message.info('取消')
            }
          })
          this.setStates(data)
        } else {
          this.setStates(data)
        }
      }
    },
    // 取消修改树节点
    CancelChange(data) {
      this.$Notice.info({
        title: '取消修改'
      })
      this.setStates(data)
    },
    // 点击Tree节点触发
    handleClickTreeNode(data) {
      console.log('当前点击' + data.title)
    }
  }
}
</script>
<style scoped>
/* .sideBar .ivu-layout-sider {
  width: 500px !important;
} */
/* 更改header的样式 */
.ivu-layout-header {
  background: #fff;
  /* height: 15px; */
}
/* header里面的内容 */

/* color: #fff; */
/* height: 15px; */

/* 面包屑导航 前几个*/
.ivu-breadcrumb {
  color: #333;
  text-align: left;
}
/* 面包屑导航最后一个 */
.ivu-breadcrumb > span:last-child {
  color: #222;
}

/* 更改content的样式 */
.ivu-layout-content {
  background: #fff;
  /* text-align: left; */
}

/* content里面的内容 */
.content1 {
  color: #333;
}

/* 树形控件的箭头 */
.demo-tree-render {
  /* background: #fff; */
  color: #fff;
}
.demo-tree-render .ivu-tree-title {
  width: 100%;
}
/* 树形结构的标签 */
/* .ivu-tree-children {
  color: #fff;
} */

.ivu-tree ul li {
  color: #333;
}
.ivu-layout-sider-children {
  width: 350px !important;
}

/* 全部侧边栏 */
.ivu-layout-sider {
  background: #fff;
}

/* 实现编辑按钮的隐藏功能 */
.btnNone {
  display: none;
}
/* .hhhaha:hover{color:aqua} */
.hhhaha:hover .btnNone {
  display: inline-block;
}

.hhhaha:hover {
  font-weight: 600;
  color: #275cd4;
}
</style>
